package com.mall.common.controller;

import static com.mall.common.Constants.OPERATE_TYPE_AUTHORITY;
import static com.mall.common.Constants.OPERATE_TYPE_NORMAL;

import java.io.File;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mall.b2c.util.SettingUtils;
import com.mall.common.bean.FileWrap;
import com.mall.common.bean.Message;
import com.mall.common.bean.Order;
import com.mall.common.bean.User;
import com.mall.common.domain.manage.Menu;
import com.mall.common.domain.manage.Menu.MenuType;
import com.mall.common.domain.manage.Operate;
import com.mall.common.exception.NoticeException;
import com.mall.common.hibernate.Finder;
import com.mall.common.service.MenuService;
import com.mall.common.service.OperateService;
import com.mall.common.util.AppContext;
import com.mall.common.util.EnumUtils;
import com.mall.common.util.PropertiesHelper;
import com.mall.common.util.ResponseUtils;
import com.mall.common.validation.annotation.RequiredFieldValidator;
import com.mall.common.validation.annotation.RequiredStringValidator;
import com.mall.common.validation.annotation.Validations;

/**
 * 后台Action类 - 首页
 */
@Controller
@RequestMapping("/admin/system/menu")
public class MenuController extends BaseController {
	
	@Resource private MenuService menuService;
	@Resource private OperateService operateService;
	private static String ICON_PATH = "resource/thirdparty/ligerUI/skins/icons/32X32";
	// 列表
	@RequestMapping(value="/checkMenuNo", method=RequestMethod.POST)
	@ResponseBody
	public String checkMenuNo(Menu menu, String oldValue) {
		String newValue = menu.getMenuNo();
		if (menuService.isUnique("menuNo", oldValue, newValue)) {
			return "true";
		} else {
			return "false";
		}
	}
	
	@RequestMapping(value="/loadLeftMenu", method=RequestMethod.GET)
	@ResponseBody
	public JSONArray loadLeftMenu(Menu menu, String oldValue) {
		User currUser = getUser();
		if(currUser == null){
			return null;
		}
		List<Long> roleIds = null;
		if(!currUser.isSystemManager()){
			roleIds = currUser.getRoleListIds();
		}
		List<Menu> menuList = menuService.getMenuTree(roleIds);
		if(menuList == null || menuList.size() == 0){
			return null;
		}
		JSONArray jArray = new JSONArray();
		for(int i=0; i<menuList.size(); i++){
			jArray.add(menuList.get(i).getJson());
		}
		return jArray;
	}
	
	// 列表
	@RequestMapping(value="/manager", method=RequestMethod.GET)
	public String manager() {
		return "/admin/system/menu/manager";
	}
	
	// 列表
	@RequestMapping(value={"/detail"}, method=RequestMethod.GET)
	public String detail(String id, Model model) {
		Menu menu = null;
		Menu parentMenu = null;
		List<Menu> subMenuList = null;
		List<Operate> normalActionList = null;
		List<Operate> authorActionList = null;
		if (StringUtils.isBlank(id) || "null".equals(id)) {
			menu = Menu.genRoot();
			Finder finder = Finder.create("from Menu menu");
			finder.append(" where menu.upDomain is null");
			finder.setOrder(Order.asc("priority"));
			subMenuList = finder.findHQLList();
		} else if (Pattern.matches("^\\d+$", id)) {
			menu = menuService.find(Long.valueOf(id));
			if(menu == null){
				throw new NoticeException("菜单不存在");
			}
			// 查询父菜单
			if (menu.getUpDomain() != null) {
				if (menu.getUpDomain().getId() == null) {
					parentMenu = Menu.genRoot();
				} else {
					parentMenu = menuService.find(menu.getUpDomain().getId());
				}
			}
			
			//查询子菜单
			if(MenuType.MENUTYPE_PARENT.equals(menu.getType())){
				subMenuList = menu.getSubMenuList();
			}
			
			//查询动作
			if(MenuType.MENUTYPE_NODE.equals(menu.getType())){
				normalActionList = operateService.getOperatesWidthCondition(menu.getId(), OPERATE_TYPE_NORMAL);
				
				authorActionList = operateService.getOperatesWidthCondition(menu.getId(), OPERATE_TYPE_AUTHORITY);
			}
		} else {
			throw new NoticeException("菜单不存在");
		}
		model.addAttribute("menu", menu);
		model.addAttribute("parentMenu", parentMenu);
		model.addAttribute("subMenuList", subMenuList);
		model.addAttribute("isDelete", false);
		model.addAttribute("normalActionList", normalActionList);
		model.addAttribute("authorActionList", authorActionList);
		return "/admin/system/menu/detail";
	}
	
	@RequestMapping(value="/tree", method=RequestMethod.GET)
	public String menuTree() {
		return "/admin/system/menu/tree";
	}
	
	@RequestMapping(value="/treeData", method=RequestMethod.POST)
	@ResponseBody
	public JSONArray treeData(Long id) {
		JSONArray jarr = new JSONArray();
		List<Menu> menus = menuService.getAllMenus();
		JSONObject jObj = new JSONObject();
		jObj.put("name", SettingUtils.get().getName());
		jarr.add(jObj);
		for(Menu menu : menus){
			jObj = new JSONObject();
			jObj.put("id", menu.getId());
			jObj.put("name", menu.getName());
			Long parentId = menu.getParentId();
			if(parentId != null){
				jObj.put("parentId", parentId);
			}
			jarr.add(jObj);
		}
		return jarr;
	}
	
	@RequestMapping(value="/middle", method=RequestMethod.GET)
	public String middle() {
		return "/admin/system/menu/middle";
	}

	@RequestMapping(value="/add", method=RequestMethod.GET)
	public String add(Long parent_id, Model model) {
		Menu parentMenu = null;
		if(parent_id != null){
			parentMenu = menuService.find(parent_id);
		}else{
			parentMenu = Menu.genRoot();
		}
		model.addAttribute("parentMenu", parentMenu);
		model.addAttribute("menuTypes", EnumUtils.enumProp2NameMap(MenuType.class, "name"));
		return "/admin/system/menu/add";
	}
	
	@Validations(
			requiredStrings = {
					@RequiredStringValidator(fieldName="name",message="菜单名称不能为空"),
					@RequiredStringValidator(fieldName="menuNo",message="菜单编号不能为空")
			},
			requiredFields = {
					@RequiredFieldValidator(fieldName="type",message="菜单类型不能为空")
			}
	)
	@RequestMapping(value="/add", method=RequestMethod.POST)
	public String add(Menu menu, HttpServletResponse response) {
		if(!menuService.isUnique("menuNo", null, menu.getMenuNo())){
			throw new NoticeException("菜单编号重复");
		}
		if(MenuType.MENUTYPE_LINE.equals(menu.getType())){
			//分隔线
			menu.setName("-- 分隔线 --");
			menu.setOperate(null);
			menuService.persist(menu);
		}else if(MenuType.MENUTYPE_PARENT.equals(menu.getType())){
			//有子菜单
			menu.setOperate(null);
			menuService.persist(menu);
		}else if(MenuType.MENUTYPE_NODE.equals(menu.getType())){
			Operate operate = menu.getOperate();
			operate.setType(OPERATE_TYPE_NORMAL);
			operate.setMenu(menu);
			operate.setName("菜单所属动作");
			menuService.persist(menu);
		}
		JSONObject jObj = new JSONObject();
		jObj.put("id", menu.getId());
		jObj.put("name", menu.getName());
		Long parentId = menu.getParentId();
		jObj.put("parentId", parentId);
		return ResponseUtils.renderJSON(jObj, response);
	}
	
	@RequestMapping(value="/update/{id}", method=RequestMethod.GET)
	public String update(@PathVariable Long id, Model model) {
		Menu menu = menuService.find(id);
		model.addAttribute("menu", menu);
		model.addAttribute("menuTypes", EnumUtils.enumProp2NameMap(MenuType.class, "name"));
		return "/admin/system/menu/edit";
	}

	@Validations(
			requiredStrings = {
					@RequiredStringValidator(fieldName="name",message="菜单名称不能为空"),
					@RequiredStringValidator(fieldName="menuNo",message="菜单编号不能为空")
			},
			requiredFields = {
					@RequiredFieldValidator(fieldName="id",message="菜单不存在"),
					@RequiredFieldValidator(fieldName="type",message="菜单类型不能为空")
			}
	)
	@RequestMapping(value="/update", method=RequestMethod.POST)
	public String update(Menu menu, HttpServletResponse response) {
		if(!menuService.isUniqueById("menuNo", menu.getId(), menu.getMenuNo())){
			throw new NoticeException("菜单编号重复");
		}
		if(MenuType.MENUTYPE_NODE.equals(menu.getType()) && menu.getOperate() == null){
			throw new NoticeException("节点菜单的动作不能为空!");
		}
		if(MenuType.MENUTYPE_NODE.equals(menu.getType())){
			menu.getOperate().setMenu(menu);
			menu.getOperate().setType(2);
		}
		menuService.updateByUpdater(menu);
		return ResponseUtils.renderJSON(menu, response);
	}

	@RequestMapping(value="/delete", method=RequestMethod.POST)
	public String delete(Long id, HttpServletResponse response) {
		Menu menu = menuService.find(id);
		menuService.remove(id);
		return ResponseUtils.renderJSON(menu, response);
	}
	
	@RequestMapping(value="/getIcons", method=RequestMethod.POST)
	@ResponseBody
	public JSONArray getIcons() {
		String real_path = AppContext.getAppRealPath(ICON_PATH);
		File dir = new File(real_path);
		List<FileWrap> fileWrapList = new FileWrap(dir).getChild();
		JSONArray arrayJson = new JSONArray();
		String pattern = null;
		if(File.separator.equals("\\")){
			pattern = "(\\\\resource\\\\thirdparty.*)";
		}else{
			pattern = "(/resource/thirdparty.*)";
		}
		Pattern p = Pattern.compile(pattern, 2 | Pattern.DOTALL);
		if(fileWrapList != null && fileWrapList.size() > 0){
			for(int i=0, len=fileWrapList.size(); i<len; i++){
				FileWrap fileWrap = fileWrapList.get(i);
				
				String path = fileWrap.getFile().getPath();
				Matcher m = p.matcher(path);
				if (m.find()) {
					path  = m.group(1);
					path = path.replaceAll("\\\\", "/");
					arrayJson.add(path);
				}
			}
		}
		
		//增加配置文件中的路径图标
		Properties properties = PropertiesHelper.getPropertiesByPrefix("config", "silkicons_");
		if(properties != null && properties.size() > 0){
			for(Object key : properties.keySet()){
				String value = (String)properties.get(key);
				arrayJson.add(AppContext.getAppRealPath(value));
			}
		}
		return arrayJson;
	}

	@Validations(
		requiredFields = {
			@RequiredFieldValidator(fieldName = "ids", message = "ID非法!"),
			@RequiredFieldValidator(fieldName = "priority", message = "排序非法!")
		}
	)
	@RequestMapping(value="/updateMenuPriority", method=RequestMethod.POST)
	public String updateMenuPriority(Long[] ids, Integer[] priority, HttpServletResponse response){
		if(ids.length != priority.length){
			throw new NoticeException("ids长度与排序的长度不一致!");
		}
		menuService.updateMenuPriority(ids, priority);
		return ResponseUtils.renderJSON(Message.success("mall.message.success", null), response);
	}
}